﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Web7.Ioc;

namespace Web7.Mvc.ViewEngines
{
    public interface IAwareViewEngine : IDependency, IViewEngine
    {
    }

    public class AwareViewEngine : IAwareViewEngine
    {
        private readonly IViewEngineServiceProvider _viewEngineServiceProvider;

        public AwareViewEngine(IViewEngineServiceProvider viewEngineServiceProvider)
        {
            _viewEngineServiceProvider = viewEngineServiceProvider;
        }

        public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
        {
            return _viewEngineServiceProvider.FindPartialView(controllerContext, partialViewName, useCache);
        }

        public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            return _viewEngineServiceProvider.FindView(controllerContext, viewName, masterName, useCache);
        }

        public void ReleaseView(ControllerContext controllerContext, IView view)
        {
            var layoutView = (LayoutView)view;
            layoutView.ReleaseView(controllerContext, view);
        }

        class LayoutView : IView, IViewDataContainer
        {
            private readonly Action<ViewContext, TextWriter, IViewDataContainer> _render;
            private readonly Action<ControllerContext, IView> _releaseView;

            public LayoutView(Action<ViewContext, TextWriter, IViewDataContainer> render, Action<ControllerContext, IView> releaseView)
            {
                _render = render;
                _releaseView = releaseView;
            }

            public ViewDataDictionary ViewData { get; set; }

            public void Render(ViewContext viewContext, TextWriter writer)
            {
                ViewData = viewContext.ViewData;
                _render(viewContext, writer, this);
            }

            public void ReleaseView(ControllerContext context, IView view)
            {
                _releaseView(context, view);
            }
        }
    }
}
